package cn.lili.modules.order.order.entity.dto;


import cn.hutool.core.annotation.PropIgnore;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.promotion.entity.vos.PromotionSkuVO;
import com.google.gson.Gson;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 商城流水，细节到orderItem
 *
 * @author Chopper
 * @since 2020/11/17 7:25 下午
 */
@Data
@Slf4j
public class PriceDetailDTO implements Serializable {


    private static final long serialVersionUID = 8808470688518188146L;


    //===============================================payment=================================================
    //流水金额（实际支付金额）
    @ApiModelProperty(value = "流水金额(入账 出帐金额) = goodsPrice + freight - discountPrice - couponPrice + updatePrice")
    private Double flowPrice = 0D;


    //支付积分
    @ApiModelProperty(value = "支付积分")
    private Double payPoint = 0D;

    @ApiModelProperty(value = "支付红包")
    private Integer payRedPack = 0;


    //============================================end payment================================================


    //============================================update price================================================

    //如果修改订单金额，则需要对订单信息进行重新计算
    @ApiModelProperty(value = "订单修改金额")
    private Double updatePrice = 0D;

    //============================================end update price================================================

    //============================================base================================================
    // 订单原始总价格=商品总金额（商品原价）+配送费

    @ApiModelProperty(value = "订单原始总价格 默认等于流水金额 ")
    private Double originalPrice = 0D;

    @ApiModelProperty(value = "商品总金额（商品原价）")
    private Double goodsPrice = 0D;
    @ApiModelProperty(value = "优惠活动金额")
    private Double discountPrice = 0D;

    @ApiModelProperty(value = "优惠券金额")
    private Double couponPrice = 0D;

    @ApiModelProperty(value = "店铺配送费")
    private Double freightPrice = 0D;

    //============================================end base================================================


    //===========================================supplier========================================================
    @ApiModelProperty(value = "供应商商品总价")
    private Double supplierGoodsPrice = 0D;

    @ApiModelProperty(value = "供应商订单金额=供应商商品总价+供应商物流费用")
    private Double supplierOrderPrice = 0D;

    @ApiModelProperty(value = "平台收取交易佣金比例")
    private Double supplierCommissionPoint = 0D;

    @ApiModelProperty(value = "平台收取供应商交易佣金金额=(supplierGoodsPrice(供应商商品总价) * platFormCommissionPoint(平台佣金比例))/100")
    private Double supplierCommissionPrice = 0D;

    @ApiModelProperty(value = "供应商配送费")
    private Double supplierFreightPrice = 0D;


    @ApiModelProperty(value = "供应商结算金额 = 供应商商品总价(supplierGoodsPrice)-供应商佣金计算(supplierCommissionPrice)+供应商配送费" +
            "(supplierFreightPrice)")
    private Double supplierSettlementPrice = 0D;
    //=======================================end supplier====================================================

    //=============================================seller=========================================================

    @ApiModelProperty(value = "商家盈余金额 = 实际支付金额(flowPrice)-供应订单金额")
    private Double surplusAmountPrice = 0D;

    @ApiModelProperty(value = "店铺交易佣金比例")
    private Double storeCommissionPoint = 0D;


    @ApiModelProperty(value = "营销列表 或涉及店铺承担部分运营成本")
    private List<SiteMarketingCost> siteMarketingCosts = new ArrayList<>();


    //SiteMarketingCost.countStoreMarketingCost(营销列表) 平台补贴营销费用
    @ApiModelProperty(value = "平台级别活动，店铺营销费用统计，用作补贴")
    private Double storeMarketingCost = 0D;

    @ApiModelProperty(value = "平台收取店铺交易佣金金额=surplusAmountPrice(店铺盈余金额) * storeCommissionPoint(平台佣金比例)/100")
    private Double storeCommissionPrice = 0D;

    @ApiModelProperty(value = "分销商返现支出")
    private Double distributorSettlementPrice = 0D;

    @ApiModelProperty(value = "商家结算金额=" +
            "店铺盈余费用(surplusAmountPrice)" +
            "+店铺营销费用(storeMarketingCost)" +
            "-平台收取店铺交易佣金金额(storeCommissionPrice)" +
            "-分销商返现支出(distributorSettlementPrice)" +
            "+店铺配送费(freightPrice)")
    private Double sellerSettlementPrice = 0D;
    //============================================end seller=====================================================


    //============================================profitsharing================================================

    //flowPrice(实际支付金额)
    //          =distributorSettlementPrice(分销商返现支出)
    //          +sellerSettlementPrice(商家结算金额)
    //          +supplierSettlementPrice(供应商结算金额)
    //          +platformSettlementPrice(平台结算金额)


    @ApiModelProperty(value = "平台盈利金额=实际支付金额(flowPrice)-商家结算金额(sellerSettlementPrice)-供应商结算金额(supplierSettlementPrice)")
    private Double platformSettlementPrice = 0D;

    @ApiModelProperty(value = "店铺获得的绿色积分分佣")
    private Double storeGreenScore = 0D;

    @ApiModelProperty(value = "供应商获得的绿色积分分佣")
    private Double supplierGreenScore = 0D;

    @ApiModelProperty(value = "用户获得的绿色积分分佣")
    private Double memberGreenScore = 0D;

    @ApiModelProperty(value = "城市站点获得的绿色积分分佣")
    private Double siteGreenScore = 0D;

    @ApiModelProperty(value = "订单地址所在城市站点获得的绿色积分分佣")
    private Double siteAddressGreenScore = 0D;

    @ApiModelProperty(value = "绿色公益获得的绿色积分分佣")
    private Double greenCommonwealGreenScore = 0D;

    @ApiModelProperty(value = "f分抵扣金额")
    private Double fmoney = 0D;

    @ApiModelProperty(value = "最大可抵扣F分")
    private Double maxFmoney = 0D;

    @ApiModelProperty(value = "商品总配置绿色积分")
    private Double greenScore = 0D;

    @ApiModelProperty(value = "全返卷抵扣金额")
    private Double returnActivityUserPrice = 0D;

    @ApiModelProperty(value = "工会获得的绿色积分分佣")
    private Double unionGreenScore = 0D;

    @ApiModelProperty(value = "城主获得的绿色积分分佣")
    private Double castellanGreenScore = 0D;

    @ApiModelProperty(value = "上推佣金（店主-下级用户订单分佣）")
    private Double lowerGreenScore = 0D;

    @ApiModelProperty(value = "上推佣金（店主-下级用户订单分佣）")
    private Double lowerSubGreenScore = 0D;


    private Boolean specialOrder = false;

    @ApiModelProperty(value = "自购减免金额")
    private Double omitGreenScore = 0D;

    //============================================end profitsharing================================================


    /**
     * 参与的促销活动
     */
    @PropIgnore
    @ApiModelProperty(value = "参与的促销活动")
    private List<PromotionSkuVO> joinPromotion = new ArrayList<>();


    public PriceDetailDTO() {
    }

    /**
     * 通过json获取模型
     *
     * @param json json
     * @return PriceDetailDTO
     */
    public static PriceDetailDTO getModel(String json) {
        if (CharSequenceUtil.isEmpty(json)) {
            return null;
        }
        try {
            return new Gson().fromJson(json, PriceDetailDTO.class);
        } catch (Exception e) {

            return null;
        }
    }

    public void setFreightPrice(Double freightPrice) {
        this.freightPrice = freightPrice;
    }

    /**
     * 写入修改金额，自动计算订单各个金额
     *
     * @param updatePrice 修改后的订单金额
     */
    public void setUpdatePrice(Double updatePrice) {
        this.updatePrice = updatePrice;
        this.recount();
    }

    /**
     * 全部重新计算
     */
    public void recount() {
        //log.info("begin   flowPrice == {}" ,flowPrice);
        //流水金额(入账 出帐金额) = "流水金额(入账 出帐金额) = goodsPrice + freight - discountPrice - couponPrice + updatePrice"
        //102
        this.flowPrice = CurrencyUtil.sub(
                CurrencyUtil.add(goodsPrice, freightPrice),
                CurrencyUtil.add(discountPrice, couponPrice,returnActivityUserPrice));
        //减去店主自购减免
        //101.4
        this.flowPrice = CurrencyUtil.sub(flowPrice,omitGreenScore);

        //log.info("end  flowPrice == {}" ,flowPrice);
        //log.info("goodsPrice == {} freightPrice == {} discountPrice =={}  couponPrice == {} " ,goodsPrice, freightPrice, discountPrice, couponPrice);
        //如果商家修改订单金额，则订单进行价格重新计算
        if (updatePrice != 0) {
            flowPrice = CurrencyUtil.add(flowPrice, updatePrice);
        } else {
            //如果订单没有修改价格，则流水金额赋值给原始订单金额
            originalPrice = flowPrice;
        }

        //计算供应商结算金额
        recountSupplier();
        //计算商家结算金额
        recountSeller();
        //计算平台结算金额
        recountPlatform();
//        //计算绿色积分分佣
        recountGreenScore();
    }

    /**
     * 计算绿色积分分佣金额
     */
    public void recountGreenScore() {

    }

    private void recountSeller() {
        if (specialOrder) {
            return;
        }
        //商家盈余金额 = 实际支付金额(flowPrice)-供应订单金额
        surplusAmountPrice = CurrencyUtil.sub(flowPrice, supplierOrderPrice);

        //
        storeMarketingCost = SiteMarketingCost.countStoreMarketingCost(siteMarketingCosts);

        //平台收取店铺交易佣金金额=surplusAmountPrice(店铺盈余金额) * storeCommissionPoint(平台佣金比例)/100

        //需额外考虑极端情况，盈余金额小于0 的情况
        if (surplusAmountPrice <= 0) {
            storeCommissionPrice = 0D;
        } else {
            storeCommissionPrice =
                    CurrencyUtil.mul(surplusAmountPrice, storeCommissionPoint);
        }
        //商家结算金额="店铺盈余费用(surplusAmountPrice)" +
        //          "-平台收取店铺交易佣金金额(storeCommissionPrice)" +
        //          "-分销商返现支出(distributorSettlementPrice)" +
        //          "+店铺营销费用(storeMarketingCost)"
        sellerSettlementPrice = CurrencyUtil.add(CurrencyUtil.sub(surplusAmountPrice, storeCommissionPrice,
                distributorSettlementPrice), storeMarketingCost);
    }

    private void recountSupplier() {
        //供应商商品总价 = 供应商商品总价(supplierGoodsPrice)+供应商配送费(supplierFreightPrice)
        supplierOrderPrice = CurrencyUtil.add(supplierGoodsPrice, supplierFreightPrice);
        //供应商佣金计算
        supplierCommissionPrice =
                CurrencyUtil.mul(supplierGoodsPrice, supplierCommissionPoint);
        //供应商结算金额 = 供应商商品总价(supplierGoodsPrice)-供应商佣金计算(supplierCommissionPrice)+供应商配送费(supplierFreightPrice)
        supplierSettlementPrice = CurrencyUtil.add(
                CurrencyUtil.sub(supplierGoodsPrice, supplierCommissionPrice),
                supplierFreightPrice);
    }

    private void recountPlatform() {
        //平台盈利金额=实际支付金额(flowPrice)-商家结算金额(sellerSettlementPrice)-供应商结算金额(supplierSettlementPrice)
        platformSettlementPrice = CurrencyUtil.sub(flowPrice, sellerSettlementPrice, supplierSettlementPrice, distributorSettlementPrice);
    }

    /**
     * 累加金额
     */
    public void increase(PriceDetailDTO priceDetailDTO) {
        //自我累加
        this.goodsPrice = CurrencyUtil.add(this.goodsPrice, priceDetailDTO.getGoodsPrice());
        // 绿色积分累加
        this.greenScore = this.greenScore + priceDetailDTO.getGreenScore();
        this.maxFmoney = this.maxFmoney + priceDetailDTO.getMaxFmoney();

        this.freightPrice = CurrencyUtil.add(this.freightPrice, priceDetailDTO.getFreightPrice());
        this.discountPrice = CurrencyUtil.add(this.discountPrice, priceDetailDTO.getDiscountPrice());
        this.couponPrice = CurrencyUtil.add(this.couponPrice, priceDetailDTO.getCouponPrice());
        this.updatePrice = CurrencyUtil.add(this.updatePrice, priceDetailDTO.getUpdatePrice());
        this.originalPrice = CurrencyUtil.add(this.originalPrice, priceDetailDTO.getOriginalPrice());
        this.flowPrice = CurrencyUtil.add(this.flowPrice, priceDetailDTO.getFlowPrice());
        this.surplusAmountPrice = CurrencyUtil.add(this.surplusAmountPrice, priceDetailDTO.getSurplusAmountPrice());
        this.storeMarketingCost = CurrencyUtil.add(this.storeMarketingCost, priceDetailDTO.getStoreMarketingCost());
        this.storeCommissionPrice = CurrencyUtil.add(this.storeCommissionPrice,
                priceDetailDTO.getStoreCommissionPrice());
        this.sellerSettlementPrice = CurrencyUtil.add(this.sellerSettlementPrice,
                priceDetailDTO.getSellerSettlementPrice());
        this.supplierOrderPrice = CurrencyUtil.add(this.supplierOrderPrice, priceDetailDTO.getSupplierOrderPrice());
        this.supplierGoodsPrice = CurrencyUtil.add(this.supplierGoodsPrice, priceDetailDTO.getSupplierGoodsPrice());
        this.supplierCommissionPrice = CurrencyUtil.add(this.supplierCommissionPrice,
                priceDetailDTO.getSupplierCommissionPrice());
        this.supplierFreightPrice = CurrencyUtil.add(this.supplierFreightPrice,
                priceDetailDTO.getSupplierFreightPrice());
        this.supplierSettlementPrice = CurrencyUtil.add(this.supplierSettlementPrice,
                priceDetailDTO.getSupplierSettlementPrice());
        this.platformSettlementPrice = CurrencyUtil.add(this.platformSettlementPrice,
                priceDetailDTO.getPlatformSettlementPrice());
        this.distributorSettlementPrice = CurrencyUtil.add(this.distributorSettlementPrice,
                priceDetailDTO.getDistributorSettlementPrice());
        this.payPoint = this.payPoint + priceDetailDTO.getPayPoint();
        this.payRedPack = this.payRedPack + priceDetailDTO.getPayRedPack();
        this.returnActivityUserPrice = CurrencyUtil.add(this.returnActivityUserPrice, priceDetailDTO.getReturnActivityUserPrice());
    }

    /**
     * 批量累加
     *
     * @param priceDetailDTOS 累加对象
     */
    public void accumulationPriceDTO(List<PriceDetailDTO> priceDetailDTOS) {
        for (PriceDetailDTO price : priceDetailDTOS) {
            this.increase(price);
        }
    }

    // 绿色积分累加
    private void increaseGreenScore(PriceDetailDTO priceDetailDTO){
        this.siteAddressGreenScore = CurrencyUtil.add(this.siteAddressGreenScore,priceDetailDTO.getSiteAddressGreenScore());
        this.siteGreenScore = CurrencyUtil.add(this.siteGreenScore,priceDetailDTO.getSiteGreenScore());
        this.unionGreenScore = CurrencyUtil.add(this.unionGreenScore,priceDetailDTO.getUnionGreenScore());
        this.castellanGreenScore = CurrencyUtil.add(this.castellanGreenScore,priceDetailDTO.getCastellanGreenScore());
        this.lowerGreenScore = CurrencyUtil.add(this.lowerGreenScore,priceDetailDTO.getLowerGreenScore());
        this.lowerSubGreenScore = CurrencyUtil.add(this.lowerSubGreenScore,priceDetailDTO.getLowerSubGreenScore());
        this.storeGreenScore = CurrencyUtil.add(this.storeGreenScore,priceDetailDTO.getStoreGreenScore());
        this.memberGreenScore = CurrencyUtil.add(this.memberGreenScore,priceDetailDTO.getMemberGreenScore());
        this.greenCommonwealGreenScore = CurrencyUtil.add(this.greenCommonwealGreenScore,priceDetailDTO.getGreenCommonwealGreenScore());
    }

    /**
     * 批量累加
     *
     * @param priceDetailDTOS 累加对象
     */
    public void accumulationGreenPriceDTO(List<PriceDetailDTO> priceDetailDTOS) {
        for (PriceDetailDTO price : priceDetailDTOS) {
            this.increaseGreenScore(price);
        }
    }

    // F分累加
    private void increaseFmoneyScore(PriceDetailDTO priceDetailDTO){
        this.fmoney = CurrencyUtil.add(this.fmoney,
                priceDetailDTO.getFmoney());
    }

    /**
     * 批量累加
     *
     * @param priceDetailDTOS 累加对象
     */
    public void accumulationFmoneyPriceDTO(List<PriceDetailDTO> priceDetailDTOS) {
        for (PriceDetailDTO price : priceDetailDTOS) {
            this.increaseFmoneyScore(price);
        }
    }

    // F分累加
    private void increaseFlowScore(PriceDetailDTO priceDetailDTO){
        this.flowPrice = CurrencyUtil.add(this.flowPrice,
                priceDetailDTO.getFlowPrice());
    }

    /**
     * 批量累加
     *
     * @param priceDetailDTOS 累加对象
     */
    public void accumulationFlowPriceDTO(List<PriceDetailDTO> priceDetailDTOS) {
        for (PriceDetailDTO price : priceDetailDTOS) {
            this.increaseFlowScore(price);
        }
    }

    public void initSiteMarketingCost() {
        if (siteMarketingCosts != null) {
            siteMarketingCosts = new ArrayList<>();
        }
    }

    public void addSiteMarketingCost(SiteMarketingCost siteMarketingCost) {
        if (siteMarketingCosts == null) {
            siteMarketingCosts = new ArrayList<>();
        }
        siteMarketingCosts.add(siteMarketingCost);
    }

    public void setDiscountPrice(Double discountPrice) {
        this.discountPrice = discountPrice;
        promotionPriceHandler();
    }

    public void setCouponPrice(Double couponPrice) {
        this.couponPrice = couponPrice;
        promotionPriceHandler();
    }

    /**
     * 如果促销金额+优惠券金额大于商品金额问题处理
     */
    private void promotionPriceHandler() {
        if (couponPrice == null || discountPrice == null) {
            return;
        }
        //如果订单优惠总额>商品金额，则处理一下数据，使得两数相加<=商品金额
        if (CurrencyUtil.add(couponPrice, discountPrice) > goodsPrice) {
            couponPrice = CurrencyUtil.sub(goodsPrice, discountPrice);
            this.setCouponPrice(couponPrice);
        }
    }

    /**
     * 通过json获取模型
     */
    @PropIgnore
    public String toJson() {
        return new Gson().toJson(this);
    }


    public Double getSupplierSettlementPrice() {
        if (supplierSettlementPrice == null) {
            return 0.0;
        }
        return supplierSettlementPrice;
    }

    public Double getDistributorSettlementPrice() {
        if (distributorSettlementPrice == null) {
            return 0.0;
        }
        return distributorSettlementPrice;
    }

    public Double getSellerSettlementPrice() {
        if (sellerSettlementPrice == null) {
            return 0.0;
        }
        return sellerSettlementPrice;
    }

    public Double getPlatformSettlementPrice() {
        if (platformSettlementPrice == null) {
            return 0.0;
        }
        return platformSettlementPrice;
    }

    public void setSpecialOrderSettlementPrice(Double sellerSettlementPrice) {
        this.setSpecialOrder(true);
        this.setSellerSettlementPrice(sellerSettlementPrice);
    }

}
